﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;

namespace HYRElectric.WirePlace
{
	public class ModelUpdater : IUpdater
	{
		private ModelUpdater(AddInId id)
		{
			this.m_updaterId = new UpdaterId(id, new Guid("58F1B78E-2DD0-4290-8EC1-836E76C1F562"));
		}

		public static ModelUpdater CreateInstance(AddInId id)
		{
			if (ModelUpdater._instance == null)
			{
				ModelUpdater._instance = new ModelUpdater(id);
			}
			return ModelUpdater._instance;
		}

		public static ModelUpdater GetInstance()
		{
			if (ModelUpdater._instance == null)
			{
				return ModelUpdater._instance;
			}
			return null;
		}

		public void Execute(UpdaterData data)
		{
			Document document = data.GetDocument();
			foreach (ElementId elementId in data.GetAddedElementIds())
			{
				Element element = document.GetElement(elementId);
				if (element is Wire)
				{
					ModelUpdater.InsertVertex(element as Wire, document);
				}
			}
		}

		public static void InsertVertex(Wire wire, Document doc)
		{
			int num = wire.NumberOfVertices;
			PolyLine polyLine = null;
			GeometryElement geometryElement = wire.get_Geometry(new Options
			{
				ComputeReferences = true,
				View = doc.ActiveView
			});
			if (geometryElement == null)
			{
				return;
			}
			foreach (GeometryObject geometryObject in RevitVersionFuncs.GetGeometryObjectArray(geometryElement))
			{
				if (geometryObject is PolyLine)
				{
					polyLine = (geometryObject as PolyLine);
					break;
				}
			}
			if (null == polyLine)
			{
				return;
			}
			List<XYZ> list = polyLine.GetCoordinates().ToList<XYZ>();
			if (num > 2)
			{
				List<XYZ> list2 = new List<XYZ>();
				for (int i = 1; i < num; i++)
				{
					list2.Add(wire.GetVertex(i));
				}
				try
				{
					for (int j = 1; j < num - 1; j++)
					{
						XYZ vertex = wire.GetVertex(j - 1);
						new XYZ(vertex.X, vertex.Y, 0.0);
						XYZ vertex2 = wire.GetVertex(j);
						XYZ xyz = new XYZ(vertex2.X, vertex2.Y, 0.0);
						XYZ vertex3 = wire.GetVertex(j + 1);
						new XYZ(vertex3.X, vertex3.Y, 0.0);
						double num2 = AssistFunc.mmToFeet(600.0);
						bool flag = false;
						using (List<XYZ>.Enumerator enumerator2 = list.GetEnumerator())
						{
							while (enumerator2.MoveNext())
							{
								if (enumerator2.Current.IsAlmostEqualTo(xyz, 1E-05))
								{
									flag = true;
									break;
								}
							}
						}
						if (!flag)
						{
							XYZ xyz2 = vertex3 - vertex2;
							double num3 = vertex3.DistanceTo(vertex2);
							if (Math.Abs(xyz2.Normalize().GetLength() - num3) >= 1E-05)
							{
								XYZ xyz3 = vertex2 + num2 / 3.0 * xyz2.Normalize();
								wire.InsertVertex(++j, xyz3);
								num++;
							}
						}
					}
				}
				catch (Exception)
				{
				}
			}
		}

		private static IList<XYZ> GetGeometryPoint(Wire wire, Document doc)
		{
			GeometryElement geometryElement = wire.get_Geometry(new Options
			{
				ComputeReferences = true,
				View = doc.ActiveView
			});
			List<GeometryObject> list = new List<GeometryObject>();
			foreach (GeometryObject item in geometryElement)
			{
				list.Add(item);
			}
			IList<XYZ> result = null;
			for (int i = 0; i < list.Count; i++)
			{
				GeometryObject geometryObject = list[i];
				if (geometryObject is PolyLine)
				{
					result = (geometryObject as PolyLine).GetCoordinates();
				}
			}
			return result;
		}

		public UpdaterId GetUpdaterId()
		{
			return this.m_updaterId;
		}

		public string GetUpdaterName()
		{
			return "Associative Section Updater";
		}

		public string GetAdditionalInformation()
		{
			return "Automatically moves a section to maintain its position relative to a window";
		}

		public ChangePriority GetChangePriority()
		{
			return 14;
		}

		private UpdaterId m_updaterId;

		private static ModelUpdater _instance;
	}
}
